package edu.whut.mall.admin.service.impl;


import cn.hutool.core.bean.BeanUtil;
import edu.whut.mall.admin.domain.ResourceParams;
import edu.whut.mall.admin.enums.SysStatusEnum;
import edu.whut.mall.admin.service.ISysResourcesService;
import edu.whut.mall.admin.vo.ResourceVo;
import edu.whut.mall.common.api.CommonResult;
import edu.whut.mall.mapper.SysResourcesMapper;
import edu.whut.mall.mapper.SysRoleResourcesMapper;
import edu.whut.mall.model.SysResources;
import edu.whut.mall.model.SysResourcesExample;
import edu.whut.mall.model.SysRoleResourcesExample;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: d9lab-mall
 * @description: 资源实现类
 * @author: Wayne
 * @create: 2020-03-18 09:25
 **/
@Service
@RequiredArgsConstructor
public class SysResourcesServiceImpl implements ISysResourcesService {
    private final SysResourcesMapper sysResourcesMapper;

    private final SysRoleResourcesMapper sysRoleResourcesMapper;

    @Override
    public CommonResult insertOneResource(ResourceParams resourceParams) {
        SysResourcesExample example = new SysResourcesExample();
        example.createCriteria().andUrlEqualTo(resourceParams.getUrl());
        List<SysResources> oldResource = sysResourcesMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(oldResource)) {
            return CommonResult.failed("URL资源重复");
        }
        SysResources sysResources = new SysResources();
        BeanUtil.copyProperties(resourceParams,sysResources);
        sysResources.setAvailable(SysStatusEnum.AVAILABLE.getCode());
        sysResources.setCreateTime(new Date());
        sysResources.setUpdateTime(new Date());
        int row = sysResourcesMapper.insertSelective(sysResources);
        if (row >= 0) {
            return CommonResult.success("添加成功");
        }
        return CommonResult.failed("添加失败");
    }

    @Override
    public Integer updateResource(ResourceParams resourceParams) {
        SysResources sysResources = new SysResources();
        BeanUtil.copyProperties(resourceParams,sysResources);
        sysResources.setUpdateTime(new Date());
        return sysResourcesMapper.updateByPrimaryKeySelective(sysResources);
    }

    @Override
    public List<SysResources> listResourcesByUserId(Long userId) {
        return sysResourcesMapper.listResourceByUserId(userId);
    }

    @Override
    public List<ResourceVo> listResourceVosByUserId(Long userId) {
        List<SysResources> sysResourcesList = listResourcesByUserId(userId);
        return transform2TreeResourceVo(sysResourcesList);
    }

    @Override
    public List<ResourceVo> listResourceVos() {
        List<SysResources> sysResourcesList = sysResourcesMapper.selectByExample(new SysResourcesExample());
        return transform2TreeResourceVo(sysResourcesList);

    }

    @Override
    public List<ResourceVo> listResourceVosByRoleId(Long roleId) {
        List<SysResources> sysResourcesList = sysResourcesMapper.listResourcesByRoleId(roleId);
        return transform2TreeResourceVo(sysResourcesList);
    }

    @Override
    @Transactional
    public Integer deleteOneResource(Long resourceId) {
        sysResourcesMapper.deleteByPrimaryKey(resourceId);
        SysRoleResourcesExample example = new SysRoleResourcesExample();
        example.createCriteria().andResourcesIdEqualTo(resourceId);
        return sysRoleResourcesMapper.deleteByExample(example);
    }

    /**
     * 把资源构建成树形结构
     * @param sysResources
     * @return
     */
    public List<ResourceVo> transform2TreeResourceVo(List<SysResources> sysResources){
        List<ResourceVo>  resourceVos = sysResources.stream()
                .filter(sysResource -> sysResource.getParentId().equals(0L))
                .map(sysResource->covert(sysResource,sysResources))
                .collect(Collectors.toList());

        return resourceVos;
   }

    /**
     * 从数据库转成Vo
     * @param sysResources
     * @return
     */
    public ResourceVo transform2Vo(SysResources sysResources){
        ResourceVo resourceVo = new ResourceVo();
        BeanUtil.copyProperties(sysResources,resourceVo);
        return resourceVo;
    }

    /**
     * 递归把子节点放入父节点
     * @param sysResources
     * @param ResourceNodes
     * @return
     */

    public ResourceVo covert(SysResources sysResources, List<SysResources> ResourceNodes){
        //转换成Vo
        ResourceVo resourceVo = transform2Vo(sysResources);
        List<ResourceVo> subResourceNodes=ResourceNodes.stream()
                .filter(subResourceNode->subResourceNode.getParentId().equals(resourceVo.getId()))
                .map(subResourceNode->covert(subResourceNode,ResourceNodes))
                .sorted(Comparator.comparing(ResourceVo::getSort))
                .collect(Collectors.toList());
        resourceVo.setResourceNodeList(subResourceNodes);
        return resourceVo;
    }



}
